package org.jsola.hr.service;

import org.jsola.core.Page;
import org.jsola.core.service.IService;
import org.jsola.hr.dao.IEmpSocPlanDAO;
import org.jsola.hr.dto.*;
import org.jsola.hr.entity.*;
import org.jsola.hr.query.EmpSocPlanQuery;
import org.jsola.hr.query.IncreaseDecreaseQuery;
import org.jsola.hr.vo.*;
import org.jsola.user.core.TokenUser;

import java.io.File;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;


/**
 * 增减员计划表
 *
 * @author zhr
 */
public interface IEmpSocPlanService extends IService<IEmpSocPlanDAO, EmpSocPlanDO> {

    /**
     * 新增增减员计划表
     *
     * @param empSocPlanAddDTO 新增增减员计划表DTO
     * @param tokenUser        当前用户
     * @return 增减员计划表详情信息
     */
    EmpSocPlanVO save(EmpSocPlanAddDTO empSocPlanAddDTO, TokenUser tokenUser);

    /**
     * 修改增减员计划表
     *
     * @param empSocPlanUpdateDTO 修改增减员计划表DTO
     * @param tokenUser           当前用户
     * @return 更新数量
     */
    int update(EmpSocPlanUpdateDTO empSocPlanUpdateDTO, TokenUser tokenUser);


    /**
     * 批量删除增减员计划表，物理删除，更新is_valid字段，从回收站删除
     *
     * @param tokenUser     当前用户
     * @param empSocPlanIds 增减员计划表id
     * @return 删除数量
     */
    int deleteByIds(TokenUser tokenUser, String... empSocPlanIds);

    /**
     * 根据增减员计划表id查找
     *
     * @param empSocPlanId 增减员计划表id
     * @param siteId       所属站点id
     * @return 增减员计划表详情信息
     */
    EmpSocPlanVO selectById(String empSocPlanId, String siteId);

    /**
     * 查询增减员计划表
     *
     * @param empSocPlanQuery 查询条件
     * @param siteId          所属站点id
     * @return 增减员计划表列表信息
     */
    List<EmpSocPlanListVO> select(EmpSocPlanQuery empSocPlanQuery, String siteId);

    /**
     * 查询增减员计划表记录数
     *
     * @param empSocPlanQuery 查询条件
     * @param siteId          所属站点id
     * @return 增减员计划表记录数
     */
    int selectCount(EmpSocPlanQuery empSocPlanQuery, String siteId);

    /**
     * 分页查询增减员计划表
     *
     * @param empSocPlanQuery 查询条件
     * @param siteId          所属站点id
     * @return 增减员计划表列表信息
     */
    Page<EmpSocPlanListVO> selectPage(EmpSocPlanQuery empSocPlanQuery, String siteId);


    /**
     * 根据增减员计划表id查找
     *
     * @param empSocPlanId 增减员计划表id
     * @param siteId       所属站点id
     * @return 增减员计划表
     */
    EmpSocPlanDO selectDOById(String empSocPlanId, String siteId);

    /**
     * 根据增减员计划表id列表查找
     *
     * @param planIdList 增减员计划表id列表
     * @param siteId     所属站点id
     * @return 增减员计划表
     */
    List<EmpSocPlanDO> selectByIdList(List<String> planIdList, String siteId);

    /**
     * 查询增减员计划表
     *
     * @param empSocPlanQuery 查询条件
     * @param siteId          所属站点id
     * @return 增减员计划表列表
     */
    List<EmpSocPlanDO> selectDO(EmpSocPlanQuery empSocPlanQuery, String siteId);

    /**
     * 增员 V2.0
     *
     * @param batchIncreaseDTO 增员参数
     * @param tokenUser        当前用户
     * @return 增员时间
     */
    String increase(EmpSocPlanBatchAddDTO batchIncreaseDTO, TokenUser tokenUser);

    /**
     * 减员 V2.0
     *
     * @param increaseDecreaseQuery 减员参数
     * @param tokenUser             当前用户
     * @return 创建结果
     */
    List<CheckDecreaseFailVO> decrease(IncreaseDecreaseQuery increaseDecreaseQuery, TokenUser tokenUser);

    /**
     * 增减员计划列表 V2.0
     *
     * @param empSocPlanQuery 查询参数
     * @param tokenUser       当前用户
     * @return 人员列表
     */
    Page<EmpSocPlanListVO> increaseOrDecreaseList(EmpSocPlanQuery empSocPlanQuery, TokenUser tokenUser);

    /**
     * 增减员计划列表的表头
     *
     * @param empSocPlanQuery 查询参数
     * @param tokenUser       当前用户
     * @return 表头
     */
    List<KeyNameVO> increaseOrDecreaseListHead(EmpSocPlanQuery empSocPlanQuery, TokenUser tokenUser);

    /**
     * 增减员计划顶部数量统计
     *
     * @param empSocPlanQuery 查询参数
     * @param tokenUser       当前用户
     * @return 统计结果
     */
    EmpSocTransformCountVO increaseDecreaseListCount(EmpSocPlanQuery empSocPlanQuery, TokenUser tokenUser);

    /**
     * 校验员工减员
     *
     * @param decreaseEmpIdList 员工Id
     * @param tokenUser         当前用户
     * @return 校验结果
     */
    List<CheckDecreaseVO> checkDecrease(List<String> decreaseEmpIdList, TokenUser tokenUser);

    /**
     * 查询一个用工单位下未反馈的增减员计划人数
     *
     * @param companyId 公司Id
     * @param tokenUser 当前用户
     * @return 未反馈的增减员计划人数
     */
    Integer notFeedbackCount(String companyId, TokenUser tokenUser);

    /**
     * 查询员工某月最后一条创建的增减员计划记录
     *
     * @param year   年
     * @param month  月
     * @param empId  员工Id
     * @param siteId 站点
     * @return 增减员计划记录
     */
    EmpSocPlanDO selectEmpLatestPlan(String year, String month, String empId, String siteId);

    /**
     * 查询员工某月创建的增减员计划记录
     *
     * @param year      年
     * @param month     月
     * @param empIdList 员工Id列表
     * @param siteId    站点
     * @return 增减员计划记录
     */
    List<EmpSocPlanDO> selectPlanByEmpIdList(String year, String month, List<String> empIdList, String siteId);

    /**
     * 把增员待增员变成增员,减员待减员变成减员
     *
     * @param empSocPlanDO 增减员计划
     * @return 增员减员字符串
     */
    String getPlanType(EmpSocPlanDO empSocPlanDO);

    /**
     * 根据员工Id查询这个员工反馈成功的增员计划列表
     *
     * @param empId     员工Id
     * @param tokenUser 当前用户
     * @return 增员成功的计划列表
     */
    List<EmpSocPlanDO> getSuccessPlanByEmp(String empId, TokenUser tokenUser);

    /**
     * 查修当月所有未反馈员工不区分站点
     *
     * @return 所有未反馈员工
     */
    List<EmpSocPlanDO> selectAllNotFeedback();

    /**
     * 查询某月的反馈成功的增减员计划
     *
     * @param empSocMonthDO 月份
     * @param tokenUser     当前用户
     * @return 计划列表
     */
    List<EmpSocPlanDO> selectSuccessFeedbackByMonth(EmpSocMonthDO empSocMonthDO, TokenUser tokenUser);

    /**
     * 查询员工的未反馈记录
     *
     * @param empId     员工Id
     * @param type      反馈类型
     * @param tokenUser 当前用户
     * @return 未反馈记录
     */
    List<EmpSocPlanDO> selectPlanByEmpId(String empId, Integer type, TokenUser tokenUser);

    /**
     * 导入增员
     *
     * @param file      导入EXCEL
     * @param companyId 公司Id
     * @param tokenUser 当前用户
     * @return 导入结果
     */
    ImportExcelResultListVO<ImportIncreaseDTO> importIncrease(File file, String companyId, TokenUser tokenUser);

    /**
     * 增员错误数据导出
     *
     * @param errorInfo 错误数据
     * @return 路径
     */
    String exportIncreaseErrorList(ImportExcelResultListVO<ImportIncreaseDTO> errorInfo);

    /**
     * 导入减员
     *
     * @param file      导入EXCEL
     * @param companyId 公司Id
     * @param tokenUser 当前用户
     * @return 导入结果
     */
    ImportExcelResultListVO<ImportDecreaseDTO> importDecrease(File file, String companyId, TokenUser tokenUser);

    /**
     * 减员错误数据导出
     *
     * @param errorInfo 错误数据
     * @return 路径
     */
    String exportDecreaseErrorList(ImportExcelResultListVO<ImportDecreaseDTO> errorInfo);

    /**
     * 导入增员数据入库
     *
     * @param saveDataList 入库数据
     * @param companyId    公司Id
     * @param tokenUser    当前用户
     */
    void importIncreaseSaveData(List<ImportIncreaseDTO> saveDataList, String companyId, TokenUser tokenUser);

    /**
     * 导入减员数据入库
     *
     * @param saveDataList 入库数据
     * @param companyId    公司Id
     * @param tokenUser    当前用户
     */
    void importDecreaseSaveData(List<ImportDecreaseDTO> saveDataList, String companyId, TokenUser tokenUser);

    /**
     * 增员时计算金额
     *
     * @param batchIncreaseDTO 增员参数
     * @param socProgDO        方案
     * @return
     */
    EmpSocPlanBatchAddDTO batchCalculationAmount(EmpSocPlanBatchAddDTO batchIncreaseDTO, SocProgDO socProgDO);

    /**
     * 根据方案ID查询增减员计划中使用此方案并且还未反馈的员工数量
     *
     * @param schemeId 方案Id
     * @return 员工数量
     */
    Integer selectEmpCountByScheme(String schemeId);

    /**
     * 合并增员计划到某个月的参保信息里
     *
     * @param planItemList 计划子项列表
     * @param empSocMonth  参保月
     * @param empInfo      员工
     * @param empSocPlanDO 计划
     * @param tokenUser    当前用户
     * @param future       是否是未来月增员
     */
    void increaseMerge(List<EmpSocPlanItemDO> planItemList, EmpSocMonthDO empSocMonth, EmpInfoDO empInfo,
                       EmpSocPlanDO empSocPlanDO, TokenUser tokenUser, Boolean future);

    /**
     * 合并减员计划到某个月的参保信息里
     *
     * @param monthId      参保月id
     * @param empSocPlanDO 增减员计划计划Id
     * @param future       是否是未来月减员
     * @param tokenUser    当前用户
     */
    void decreaseMerge(String monthId, EmpSocPlanDO empSocPlanDO, Boolean future, TokenUser tokenUser);

    /**
     * 根据类型初始化一个减员的计划
     *
     * @param companyId   公司Id
     * @param type        减员类型
     * @param year        年
     * @param month       月
     * @param empId       员工Id
     * @param serviceCost 服务费
     * @param tokenUser   当前用户
     * @return
     */
    EmpSocPlanDO initDecreasePlanByType(String companyId, Integer type, String year, String month,
                                        String empId, BigDecimal serviceCost, TokenUser tokenUser);

    /**
     * 根据类型初始化一个减员的计划(需要确认)
     *
     * @param companyId   公司Id
     * @param type        减员类型
     * @param year        年
     * @param month       月
     * @param empId       员工Id
     * @param serviceCost 服务费
     * @param tokenUser   当前用户
     * @return
     */
    EmpSocPlanDO initDecreasePlanByType2(String companyId, Integer type, String year, String month,
                                         String empId, BigDecimal serviceCost, TokenUser tokenUser);


    /**
     * 查找未反馈计划
     *
     * @param empId     员工Id
     * @param type      类型
     * @param socType   类型
     * @param tokenUser 当前用户
     * @return 员工未反馈计划
     */
    List<EmpSocPlanDO> findNotFeedback(String empId, Integer type, String socType, TokenUser tokenUser);

    /**
     * 查询使用对应方案的未反馈的增减员计划
     *
     * @param schemeId 方案Id
     * @param siteId   站点
     * @return 增减员计划
     */
    List<EmpSocPlanDO> selectNotFeedbackBySchemeId(String schemeId, String siteId);

    /**
     * 更改方案同步更新未反馈的增减员计划
     *
     * @param schemeId       方案Id
     * @param onlySocAmount  方案是否仅缴纳金额
     * @param schemeItemList 方案的子项
     * @param serviceCost    服务费
     * @param tokenUser      当前用户
     */
    void reAmount(String schemeId, Boolean onlySocAmount, List<SocProgItemAddDTO> schemeItemList,
                  BigDecimal serviceCost, TokenUser tokenUser);
}


